import Vue from "vue";
import VueRouter from "vue-router";
import MenuView from "@/views/common/MenuView";
import PageView from "@/views/common/PageView";
import LoginView from "@/views/login/Common";
import EmptyPageView from "@/views/common/EmptyPageView";
import HomePageView from "@/views/HomePage";
import db from "utils/localstorage";
import request from "utils/request";

const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location);
};
Vue.use(VueRouter);

let constRouter = [
  {
    path: "/login",
    name: "登录页",
    component: LoginView
  },
  {
    path: "/index",
    name: "首页",
    redirect: "/home"
  },
];

let router = new VueRouter({
  routes: constRouter
});

const whiteList = ["/login"];

let asyncRouter;

// 导航守卫，渲染动态路由
router.beforeEach(async (to, from, next) => {
  if (whiteList.indexOf(to.path) !== -1) {
    next();
  }
  let token = db.get("USER_TOKEN");
  let user = db.get("USER");
  let userRouter = db.get("USER_ROUTER", null);
  if (token.length && user) {
    if (!userRouter) {
      await getRoutes(user);
      // debugger
      db.save("USER_ROUTER", asyncRouter);
      go(to, next);
    } else {
      if (!asyncRouter) {
        asyncRouter = userRouter;
        go(to, next);
      } else {
        // userRouter = asyncRouter;
        // asyncRouter = userRouter;
        next();
      }
    }
  } else {
    next("/login");
  }
});

/**
 * @desc: api获取路由的方法
 * @param {type}
 * @return:
 * @author: youzi
 */
const getRoutes = async user => {
  await request.get(`menu/${user.usercode}`).then(res => {
    asyncRouter = res.data.data;
  });
};

function go(to, next) {
  asyncRouter = filterAsyncRouter(asyncRouter);
  router.addRoutes(asyncRouter);
  next({ ...to, replace: true });
}

/********** filterAsyncRouter() 这个函数很关键**********
 * @description: 用于过滤异步获取到的路由。
 * @param {Object []，对象数组} 用户拥有权限的路由表，形如以下格式
 * [
    {
      children: [{ path: '/home', name: '系统主页', component: 'HomePageView', icon: 'home' }],
      component: 'MenuView',
      icon: 'none',
      name: '主页',
      path: '/',
      redirect: '/home'
    }
  ]
 * @return: 返回过滤后的函数
 * @logic: 根据数据结构判断component字段的类型，分为5种情况，分别是菜单，页面，空页面，主页，其他
 * 其他页面会调用view函数，动态引入指定路径的
 */
function filterAsyncRouter(routes) {
  return routes.filter(route => {
    let component = route.component;
    if (component) {
      switch (route.component) {
        case "MenuView":
          route.component = MenuView;
          break;
        case "PageView":
          route.component = PageView;
          break;
        case "EmptyPageView":
          route.component = EmptyPageView;
          break;
        case "HomePageView":
          route.component = HomePageView;
          break;
        default:
          route.component = view(component);
      }
      if (route.children && route.children.length) {
        route.children = filterAsyncRouter(route.children);
      }
      return true;
    }
  });
}

function view(path) {
  return function(resolve) {
    import(`@/views/${path}.vue`).then(mod => {
      resolve(mod);
    });
  };
}

export default router;
